#pragma once
#include<grpcpp/grpcpp.h>
#include"message.grpc.pb.h"
#include"const.h"
#include"Singleton.h"

using grpc::Channel;
using grpc::Status;
using grpc::ClientContext;
using message::GetVarifyReq;
using message::GetVarifyRsp;
using message::VarifyService;

class RPConPool
{
public:
	RPConPool(size_t poolsize, string host, string port) : poolsize_(poolsize), host_(host), port_(port), b_stop_(false)
	{
		for (size_t i = 0; i < poolsize_; i++)
		{
			std::shared_ptr<Channel> channl = grpc::CreateChannel(host_+":"+port_, grpc::InsecureChannelCredentials());
			connection_.push(VarifyService::NewStub(channl));
		}
	}
	~RPConPool();
	void Close();
	std::unique_ptr<VarifyService::Stub> getConnection();
	void returnConnection(std::unique_ptr<VarifyService::Stub> context);
private:
	atomic<bool> b_stop_;
	std::size_t poolsize_;
	std::string host_;
	std::string port_;
	std::queue<std::unique_ptr<VarifyService::Stub>> connection_;
	std::mutex mutex_;
	std::condition_variable cond_;
};

class VerifyGrpc_Client:public Singleton<VerifyGrpc_Client>
{
	friend class Singleton<VerifyGrpc_Client>;
public:
	GetVarifyRsp GetvarifyCode(std::string email) {
		ClientContext context;
		GetVarifyRsp reply;
		GetVarifyReq request;
		request.set_email(email);
		auto stub = pool_->getConnection();

		Status status = stub->GetVarifyCode(&context, request, &reply);

		if (status.ok())
		{
			pool_->returnConnection(std::move(stub));
			return reply;
		}
		else
		{
			pool_->returnConnection(std::move(stub));
			reply.set_error(ErrorCodes::RCP_faild);
			return reply;
		}


	}


private:
	VerifyGrpc_Client();

	std::unique_ptr<RPConPool> pool_;
};

